package com.star.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.star.constant.MessageConstant;
import com.star.constant.StatusConstant;
import com.star.dto.UserLoginCodeDTO;
import com.star.dto.UserPageQueryDTO;
import com.star.dto.UserRegisterDTO;
import com.star.dto.UserLoginDTO;
import com.star.entity.User;
import com.star.exception.AccountLockedException;
import com.star.exception.AccountNotFoundException;
import com.star.exception.PasswordErrorException;
import com.star.exception.UserNotLoginException;
import com.star.mapper.UserMapper;
import com.star.properties.WeChatProperties;
import com.star.result.PageResult;
import com.star.service.UserService;
import com.star.utils.HttpClientUtil;
import com.star.vo.DishVO;
import com.star.vo.WxLoginResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

//    public static final String WX_LGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 分页查询用户
     * @param userPageQueryDTO
     * @return
     */
    public PageResult pageQuery(UserPageQueryDTO userPageQueryDTO) {
        // 开启分页查询
        PageHelper.startPage(userPageQueryDTO.getPage(), userPageQueryDTO.getPageSize());
        Page<User> page = userMapper.pageQuery(userPageQueryDTO);
        long total = page.getTotal();
        List<User> records = page.getResult();
        return new PageResult(total, records);
    }

    /**
     * 修改用户状态
     * @param status
     * @param id
     */
    public void updateStatus(Integer status, Long id) {
        User user = new User();
        user.setStatus(status);
        user.setId(id);
        userMapper.update(user);
    }

    /**
     * 用户登录
     * @param userLoginDTO
     * @return
     */
    public User login(UserLoginDTO userLoginDTO) {
        String phone = userLoginDTO.getPhone();
        String password = userLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        User user = userMapper.getByPhone(phone);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (user == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对
        //对前端传来的密码进行加密与数据库密码比对
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(user.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (Objects.equals(user.getStatus(), StatusConstant.DISABLE)) {
            //账号被锁定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return user;
    }

    /**
     * 验证码登录
     * @param userLoginCodeDTO
     * @return
     */
    public User loginByCode(UserLoginCodeDTO userLoginCodeDTO) {
        String redisCode =  redisTemplate.opsForValue().get(userLoginCodeDTO.getPhone());
        if(!Objects.equals(redisCode,userLoginCodeDTO.getCode())){
            throw new AccountLockedException(MessageConstant.CODE_ERROR);
        }
        User user = userMapper.getByPhone(userLoginCodeDTO.getPhone());
        if (user == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        return user;
    }

    /**
     * 用户注册
     * @param userRegisterDTO
     */
    public void add(UserRegisterDTO userRegisterDTO) {
        // 判断用户是否存在
        User existingUser = userMapper.getByPhone(userRegisterDTO.getPhone());
        if(existingUser != null) {
            throw new AccountLockedException(MessageConstant.ALREADY_EXISTS);
        }
        User user = new User();
        // 对象属性拷贝
        BeanUtils.copyProperties(userRegisterDTO, user);

        // 设置账户状态, 默认状态 1:正常 0:禁用
        user.setStatus(StatusConstant.ENABLE);

        // 加密密码
        user.setPassword(DigestUtils.md5DigestAsHex(userRegisterDTO.getPassword().getBytes()));

        // 设置默认用户名
        String phone = user.getPhone();
        user.setName("用户" + phone.substring(phone.length() - 4));

        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        // 公共字段自动注入
//        // 设置当前记录的创建时间和修改时间
//        employee.setCreateTime(LocalDateTime.now());
//        employee.setUpdateTime(LocalDateTime.now());
//
//        // 设置当前记录的创建人id和修改人id
//        employee.setCreateUser(BaseContext.getCurrentId());
//        employee.setUpdateUser(BaseContext.getCurrentId());

        userMapper.insert(user);
    }

    /**
     * 修改用户信息
     * @param user
     */
    public void update(User user) {
        User userDB = userMapper.getById(user.getId());
        if (userDB == null) {
            throw new UserNotLoginException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        BeanUtils.copyProperties(user, userDB);
        userMapper.update(userDB);
    }

    /**
     * 根据id查询用户信息
     * @param id
     * @return
     */
    public User getById(Long id) {
        return userMapper.getById(id);
    }

    /**
     * 调用微信接口服务，获取微信用户的openid
     * @param code
     * @return
     */
//    private WxLoginResponse getResponse(String code) {
//        // 调用微信接口服务，获得当前微信用户的openid
//        Map<String, String> map = new HashMap<>();
//        map.put("appid",weChatProperties.getAppid());
//        map.put("secret",weChatProperties.getSecret());
//        map.put("js_code",code);
//        map.put("grant_type","authorization_code");
//        String json = HttpClientUtil.doGet(WX_LGIN, map);
//
//        JSONObject jsonObject = JSON.parseObject(json);
//        WxLoginResponse response = new WxLoginResponse();
//        String openid = jsonObject.getString("openid");
//        String sessionKey = jsonObject.getString("session_key");
//        response.setOpenid(openid);
//        response.setSession_key(sessionKey);
//
//        return response;
//    }
}
